package com.mycompany.hibernatetest;

import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import org.hibernate.Session;
import org.junit.*;
import org.paul.hibernatetest.Event;
import org.paul.hibernatetest.HibernateUtil;
import org.paul.hibernatetest.Person;
import static org.junit.Assert.*;

/**
 * @date 2012-09-01 @description:参考文档
 * 1.http://docs.jboss.org/hibernate/core/3.5/reference/zh-CN/html/objectstate.html#objectstate-makingpersistent：10.11.
 * 传播性持久化（transitive persistence）
 * 2.inverse：http://blogs.warwick.ac.uk/colinyates/entry/hibernates_bizzare_interpretation/
 * 3.cascade:http://www.mkyong.com/hibernate/hibernate-cascade-example-save-update-delete-and-delete-orphan/
 * summary: 1.cascade默认为false，cascade有create, merge, save-update, delete, lock, refresh, evict, replicate
 * 对于one-to-many还有delete-orphan
 * 2.在one-to-many中，当one端inverse=false时，可用one.children级联保存子对象，此时子对象先insert，后update外键（对于外键不能为空的情况会有问题）
 * 当one端inverse=true时，hibernate将忽略one.children，此时需由子对象维护这一关系，即设置many.parent 3.
 *
 * @author paul
 */
public class CascadeTeset {

    static Session session;

    @Before
    public void beforTest() {
        session = HibernateUtil.getSessionFactory().getCurrentSession();
        //开始事务
        session.beginTransaction();
        //删除已有数据
        session.createQuery("delete from Event").executeUpdate();
        session.createQuery("delete from Person").executeUpdate();
    }

    @After
    public void afterTest() {
        //提交事务
        session.getTransaction().commit();
    }

    // @Test
//    public void testOneToManyOnSaveWithNoInverse() {
//        //初始化event
//        Event theEvent = new Event();
//        theEvent.setTitle("hellowrodl");
//        theEvent.setDate(new Date());
//        //初始化person
//        Person person = new Person();
//        person.setAge(20);
//        person.setFirstname("paul");
//        person.setLastname("lee");
//
//        Set<Event> events = new HashSet<Event>();
//        events.add(theEvent);
//        person.setEvents(events);
//        session.save(person);
//    }
  //  @Test
    public void testOneToManyOnSaveWithInverse() {
        //初始化event
        Event event = new Event();
        event.setTitle("hellowrodl");
        event.setDate(new Date());
        //初始化person
        Person person = new Person();
        person.setAge(20);
        person.setFirstname("paul");
        person.setLastname("lee");
        event.setPerson(person);
        Set<Event> events = new HashSet<Event>();
        events.add(event);
        person.setEvents(events);
        session.save(person);
        session.flush();
        
        session.evict(person);
        session.evict(event);
        person=(Person) session.load(Person.class, person.getId());
        event = (Event) session.load(Event.class, event.getId());
        
        assertEquals("event's person should now be set!", person, event.getPerson());
    }
    /**
     * 对于cascade=delete，删除父对象时，会级联删除子对象。顺序：1.先删除子对象2.删除父对象。避免外键不存在限制
     * 对于cascade不包含delete,删除父对象可能会引起外键不存在异常
     */
  // @Test
   public void testCascadeDelete(){
        //初始化event
        Event event = new Event();
        event.setTitle("hellowrodl");
        event.setDate(new Date());
        Person person = new Person();
        person.setAge(20);
        person.setFirstname("paul");
        person.setLastname("lee");
        event.setPerson(person);
        Set<Event> events = new HashSet<Event>();
        events.add(event);
        person.setEvents(events);
        session.save(person);
        session.flush();
        session.evict(person);
        session.evict(event);
        person=(Person) session.load(Person.class, person.getId());
        event = (Event) session.load(Event.class, event.getId());
        
        assertEquals("event's person should now be set!", person, event.getPerson());
        session.delete(person);
        session.flush();
        person=(Person) session.get(Person.class, person.getId());
        event = (Event) session.get(Event.class, event.getId());
        assertNull("person is null",person);
        assertNull("event is null",event);
   }
   
  /**
   * get对于不存在的记录返回null，load返回代理对象，之后操作代理对象，抛出异常
   * 
   * 
   */
   @Test
   public void testUpdate(){
        //初始化event
        Event event = new Event();
        event.setTitle("hellowrodl");
        event.setDate(new Date());
        Person person = new Person();
        person.setAge(20);
        person.setFirstname("paul");
        person.setLastname("lee");
        event.setPerson(person);
        Set<Event> events = new HashSet<Event>();
        events.add(event);
        person.setEvents(events);
        session.save(person);
        session.flush();
        session.evict(person);
        session.evict(event);
        person=(Person) session.load(Person.class, person.getId());
        event = (Event) session.load(Event.class, event.getId());
        
        assertEquals("event's person should now be set!", person, event.getPerson());
        
        Event event2=new Event();
        event2.setDate(new Date());
        event2.setPerson(person);
        event2.setTitle("the second event insert into person");
       
        person.getEvents().clear();
        person.getEvents().add(event2);
        session.saveOrUpdate(person);
        session.flush();
        
        session.evict(person);
        session.evict(event);
        session.evict(event2);
        person=(Person) session.load(Person.class, person.getId());
        event = (Event) session.get(Event.class, event.getId());
        event2 = (Event) session.load(Event.class, event2.getId());
        assertNull("event is null",event);
        assertEquals("event2's person is person",event2.getPerson(),person);
   }
    
}
